package com.learn.rabbitmq.callback;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 回调接口
 */
@Slf4j
//1.
@Component
public class MyCallBack implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {


    //2.注入到内部的实现类
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //3.
    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }


    /**
     * 交换确认回调方法
     * 1.发消息 交换机接收到了 回调
     * 1.1  保存回调消息的ID及相关信息
     * 1.2  交换机收到消息 true
     * 1.3  cause  null
     * <p>
     * 2.发消息 交换机接收失败了 回调
     * 1.1  保存回调消息的ID及相关信息
     * 1.2  交换机收到消息 false
     * 1.3  cause  失败原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = correlationData != null ? correlationData.getId() : "";
        if (ack) {
            log.info("交换机已经收到id为:{}的消息", id);
        } else {
            log.info("交换机还未收到id为:{}的消息,失败原因:{}", id, cause);
        }

    }

    //可以在当前消费传递过程中不可达目的地时将消息返回给生产者
    //只有失败时才被调用  （备份交换机的优先级比这个高  谁高执行谁）
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {

        log.info("消息->{},被交换机->{}退回,退回原因->{},路由key->{}",
                new String(returnedMessage.getMessage().getBody()),
                returnedMessage.getExchange(),
                returnedMessage.getReplyText(),
                returnedMessage.getRoutingKey());

    }
}
